/*
 * WSNSimpleBattery.h
 *
 *  Created on: Nov 24, 2013
 *      Author: Hien
 */
#include "INETDefs.h"
#include "BasicBattery.h"
#include "NotificationBoard.h"

#ifndef WSNSIMPLEBATTERY_H_
#define WSNSIMPLEBATTERY_H_

class WSNSimpleBattery : public BasicBattery {

protected:
    NotificationBoard *wnb;
    class DeviceEntry
    {
      public:
        int currentState;
        cObject * owner;
        double radioUsageCurrent[4];
        double  draw;
        int     currentActivity;
        int     numAccts;
        double  *accts;
        simtime_t   *times;
        DeviceEntry()
        {
            currentState = 0;
            numAccts = 0;
            currentActivity = -1;
            accts = NULL;
            times = NULL;
            owner = NULL;
            for (int i=0; i<4; i++)
                radioUsageCurrent[i] = 0.0;
        }
        ~DeviceEntry()
        {
            delete [] accts;
            delete [] times;
        }
    };
    typedef std::map<int,DeviceEntry*>  DeviceEntryMap;
    typedef std::vector<DeviceEntry*>  DeviceEntryVector;
    DeviceEntryMap deviceEntryMap;
    DeviceEntryVector deviceEntryVector;

public:
    virtual void    initialize(int);
        virtual int numInitStages() const {return 2;}
        virtual void    finish();
        virtual void handleMessage(cMessage *msg);
        /**
         * @brief Registers a power draining device with this battery.
         *
         * Takes the name of the device as well as a number of accounts
         * the devices draws power for (like rx, tx, idle for a radio device).
         *
         * Returns an ID by which the device can identify itself to the
         * battery.
         *
         * Has to be implemented by actual battery implementations.
         */
        virtual int registerDevice(cObject *id, int numAccts);
        virtual void registerWirelessDevice(int id, double mUsageRadioIdle, double mUsageRadioRecv, double mUsageRadioSend, double mUsageRadioSleep);

        /**
         * @brief Draws power from the battery.
         *
         * The actual amount and type of power drawn is defined by the passed
         * DrawAmount parameter. Can be an fixed single amount or an amount
         * drawn over time.
         * The drainID identifies the device which drains the power.
         * "Account" identifies the account the power is drawn from.
         */
        virtual void draw(int drainID, DrawAmount& amount, int account);
        ~WSNSimpleBattery();
        WSNSimpleBattery() {mustSubscribe = true; publish = NULL; timeout = NULL;}
        double getVoltage();
        /** @brief current state of charge of the battery, relative to its
         * rated nominal capacity [0..1]
         */
        double estimateResidualRelative();
        /** @brief current state of charge of the battery (mW-s) */
        double estimateResidualAbs();

      protected:

        cOutVector residualVec;
        cOutVector* mCurrEnergy;

        enum msgType
        {
            AUTO_UPDATE, PUBLISH,
        };

        cMessage *publish;
        cMessage *timeout;
        simtime_t lastUpdateTime;

        virtual void deductAndCheck();
        void receiveChangeNotification(int aCategory, const cObject* aDetails);

};



#endif /* WSNSIMPLEBATTERY_H_ */
